package com.ce.pms.system.custservice.service.impl;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;

import org.jmock.Expectations;
import org.jmock.Mockery;
import org.junit.After;
import org.junit.Before;
import org.junit.Test;

import com.ce.pms.base.vo.SearchVO;
import com.ce.pms.common.dao.ISysrefcodeDao;
import com.ce.pms.common.model.SysInfo;
import com.ce.pms.exception.BusinessException;
import com.ce.pms.system.custservice.dao.ICustEventKindDao;
import com.ce.pms.system.custservice.dao.IEmergencyDegreeDao;
import com.ce.pms.system.custservice.dao.IReturnVisitRuleDao;
import com.ce.pms.system.custservice.model.CustEventKindDO;
import com.ce.pms.system.custservice.model.EmergencyDegreeDO;
import com.ce.pms.system.custservice.model.ReturnVisitRuleDO;
import com.ce.pms.system.custservice.vo.ReturnVisitRuleVO;
import com.sitechasia.webx.core.support.Page;

/**
 * 描述：测试“回访规则”service
 * @author 王浩羽
 *
 */
public class ReturnVisitRuleServiceImplT extends MyJMockBaseTestCase
{

	private ReturnVisitRuleServiceImpl serviceImpl;
	private IReturnVisitRuleDao returnVisitRuleDao;
	private ICustEventKindDao custEventKindDao;
	private IEmergencyDegreeDao emergencyDegreeDao;
	
	private ReturnVisitRuleDO ruleDO;
	private ReturnVisitRuleVO ruleVO;
	
	//常量数据
	private final Long CURRENT_ID = 2008L;
	private final String CURRENT_NAME = "oldName";
	private final String CURRENT_REMARK = "oldRemark";
	private final String CURRENT_VALIDITY = "0";
	private final short CURRENT_SEQUENCE = (short)1;
	//CustEventKind 数据
	private final Long CURRENT_KIND_ID = 101L;
	private final String CURRENT_KIND_NAME = "oldKindName";
	private final String CURRENT_KIND_REMARK = "oldKindRemark";
	private final short CURRENT_KIND_SEQUENCE = (short)1;
	//EmergencyDegree 数据
	private final Long CURRENT_DEGREE_ID = 201L;
	private final String CURRENT_DEGREE_NAME = "oldDegreeName";
	private final String CURRENT_DEGREE_REMARK = "oldDegreeRemark";
	private final short CURRENT_DEGREE_SEQUENCE = (short)1;
	
	private final Long NEW_ID = 2009L;
	private final String NEW_NAME = "newName";
	private final String NEW_REMARK = "newRemark";
	private final String NEW_VALIDITY = "1";
	private final short NEW_SEQUENCE = (short)2;
	//new CustEventKind EmergencyDegree  ID
	private final Long NEW_KIND_ID = 102L;
	private final Long NEW_DEGREE_ID = 202L;
	
	private CustEventKindDO kindDO ;
	private EmergencyDegreeDO degreeDO;
	
	
	@Before
	public void setUp() throws Exception
	{
		super.setUp();
		returnVisitRuleDao = context.mock(IReturnVisitRuleDao.class);
		custEventKindDao = context.mock(ICustEventKindDao.class);
		emergencyDegreeDao = context.mock(IEmergencyDegreeDao.class);
		serviceImpl = new ReturnVisitRuleServiceImpl();
		serviceImpl.setReturnVisitRuleDao(returnVisitRuleDao);
		serviceImpl.setCustEventKindDao(custEventKindDao);
		serviceImpl.setEmergencyDegreeDao(emergencyDegreeDao);
		serviceImpl.setSysrefcodeDao(sysrefcodeDao);
		
		ruleDO = new ReturnVisitRuleDO();
		ruleVO = new ReturnVisitRuleVO();
		
		ruleDO.setKeyword(CURRENT_ID);
		ruleDO.setName(CURRENT_NAME);
		ruleDO.setRemark(CURRENT_REMARK);
		ruleDO.setSequence(CURRENT_SEQUENCE);
		ruleDO.setValidity(CURRENT_VALIDITY);
		//添加CustEventKind
		kindDO = new CustEventKindDO();
		kindDO.setKeyword(CURRENT_KIND_ID);
		kindDO.setName(CURRENT_KIND_NAME);
		kindDO.setRemark(CURRENT_KIND_REMARK);
		kindDO.setSequence(CURRENT_KIND_SEQUENCE);
		ruleDO.setCustServEventKind(kindDO);
		//添加EmergencyDegree
		degreeDO = new EmergencyDegreeDO();
		degreeDO.setKeyword(CURRENT_DEGREE_ID);
		degreeDO.setName(CURRENT_DEGREE_NAME);
		degreeDO.setRemark(CURRENT_DEGREE_REMARK);
		degreeDO.setSequence(CURRENT_DEGREE_SEQUENCE);
		ruleDO.setEmergencyDegree(degreeDO);
		//添加SysInfo
		ruleDO.setSysInfo(sysInfo);
		
		//VO暂不设置ID，如果VO有ID，使用NEW_ID
		ruleVO.setName(NEW_NAME);
		ruleVO.setRemark(NEW_REMARK);
		ruleVO.setSequence(NEW_SEQUENCE);
		ruleVO.setValidity(NEW_VALIDITY);
		ruleVO.setCustServEventKindId(CURRENT_KIND_ID);
		ruleVO.setEmergencyDegreeId(CURRENT_DEGREE_ID);
		
		
	}


	@After
	public void tearDown() throws Exception
	{
	}


	@Test
	public void testAddReturnVisitRuleFail()
	{
		ruleVO.setName(ruleDO.getName());
		// expectations
		context.checking(new Expectations() {{
			//当名称存在时，将抛出异常，保存操作不会执行
			oneOf(returnVisitRuleDao).findUniqueByName(ruleVO.getName()); will(returnValue(ruleDO));
			never(custEventKindDao).findById(ruleVO.getCustServEventKindId());
			never(emergencyDegreeDao).findById(ruleVO.getEmergencyDegreeId());
			never(sysrefcodeDao).getDate();
			never(returnVisitRuleDao).saveObject(with(any(ReturnVisitRuleDO.class))); 
	    }});
		// execute
		try
		{
			boolean returnValue = serviceImpl.addReturnVisitRule(ruleVO);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		// verify
		context.assertIsSatisfied();
	}

	@Test
	public void testAddReturnVisitRuleSuccess()
	{
		ruleVO.setCreator(SYSTEM_INFO_NEW_MODIFIER);
		// expectations
		context.checking(new Expectations() {{
			//当名称还没有存在时，保存操作执行
			oneOf(returnVisitRuleDao).findUniqueByName(ruleVO.getName()); will(returnValue(null));
	        oneOf(custEventKindDao).findById(ruleVO.getCustServEventKindId());will(returnValue(kindDO));
	        oneOf(emergencyDegreeDao).findById(ruleVO.getEmergencyDegreeId());will(returnValue(degreeDO));
	        oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
	        oneOf(returnVisitRuleDao).saveObject(with(any(ReturnVisitRuleDO.class))); will(returnValue(ruleDO));
	    }});
		// execute
		boolean returnValue = serviceImpl.addReturnVisitRule(ruleVO);
		// verify
		context.assertIsSatisfied();
		assertTrue(returnValue);
	}

	@Test
	public void testDeleteReturnVisitRuleByIdFail()
	{
		context.checking(new Expectations() {{
			oneOf(returnVisitRuleDao).deleteObjectById(CURRENT_ID);will(throwException(new RuntimeException("被引用"))); 
	    }});
		boolean returnValue = false;
		try
		{
			returnValue = serviceImpl.deleteReturnVisitRuleById(CURRENT_ID);
			fail("it should throw exception!");
		}
		catch(Exception e)
		{
			assertTrue(e instanceof BusinessException);
		}
		context.assertIsSatisfied();
		assertFalse(returnValue);
	}

	@Test
	public void testDeleteReturnVisitRuleByIdSuccess()
	{
		context.checking(new Expectations() {{
			oneOf(returnVisitRuleDao).deleteObjectById(CURRENT_ID);
	    }});
		boolean returnValue = false;
		try
		{
			returnValue = serviceImpl.deleteReturnVisitRuleById(CURRENT_ID);
		}
		catch(Exception e)
		{
			fail("it should not throw exception!");
		}
		context.assertIsSatisfied();
		assertTrue(returnValue);
	}

	@Test
	public void testEditReturnVisitRuleFail()
	{
		ruleVO.setKeyword(CURRENT_ID);
		context.checking(new Expectations() {{
			//存在待修改的对象
			oneOf(returnVisitRuleDao).findById(ruleVO.getKeyword()); will(returnValue(null));
			never(custEventKindDao).findById(ruleVO.getCustServEventKindId());
			never(emergencyDegreeDao).findById(ruleVO.getEmergencyDegreeId());
			never(sysrefcodeDao).getDate();
			never(returnVisitRuleDao).updateObject(with(any(ReturnVisitRuleDO.class)));
	    }});
		boolean returnValue = serviceImpl.editReturnVisitRule(ruleVO);
		context.assertIsSatisfied();
		assertFalse(returnValue);
	}

	@Test
	public void testEditReturnVisitRuleSuccess()
	{
		ruleVO.setKeyword(CURRENT_ID);
		ruleVO.setCreator(SYSTEM_INFO_NEW_MODIFIER); 
		final ReturnVisitRuleDO ruleDO_toEdit = new ReturnVisitRuleDO();
		copyData(ruleDO, ruleDO_toEdit);
		context.checking(new Expectations() {{
			//存在待修改的对象
			oneOf(returnVisitRuleDao).findById(ruleVO.getKeyword()); will(returnValue(ruleDO_toEdit));
			oneOf(custEventKindDao).findById(ruleVO.getCustServEventKindId());will(returnValue(kindDO));
		    oneOf(emergencyDegreeDao).findById(ruleVO.getEmergencyDegreeId());will(returnValue(degreeDO));
		    oneOf(sysrefcodeDao).getDate();will(returnValue(SYSTEM_INFO_DATE_CREATED));
			//进行修改
			oneOf(returnVisitRuleDao).updateObject(ruleDO_toEdit); will(returnValue(ruleDO_toEdit));
	    }});
		boolean returnValue = serviceImpl.editReturnVisitRule(ruleVO);
		context.assertIsSatisfied();
		assertTrue(returnValue);
		//值已经被修改
		assertEquals(ruleVO.getName(), ruleDO_toEdit.getName());
		assertEquals(ruleVO.getRemark(), ruleDO_toEdit.getRemark());
		assertEquals(ruleVO.getValidity(), ruleDO_toEdit.getValidity());
		assertTrue(ruleVO.getSequence()==ruleDO_toEdit.getSequence());
	}
	@Test
	public void testQueryAllReturnVisitRule()
	{
		//这里只做简单的size测试
		final List<ReturnVisitRuleDO> doList_toReturn = new ArrayList<ReturnVisitRuleDO>();
		final int LIST_SIZE = 2;
		for(int i = 0; i < LIST_SIZE; i++)
		{
			doList_toReturn.add(new ReturnVisitRuleDO());
		}
		context.checking(new Expectations() {{
			oneOf(returnVisitRuleDao).findAll(); will(returnValue(doList_toReturn));
	    }});
		List<ReturnVisitRuleVO>  returnValue = serviceImpl.queryAllReturnVisitRule();
		context.assertIsSatisfied();
		assertTrue(LIST_SIZE == returnValue.size());
	}


	@Test
	public void testQueryReturnVisitRuleListByPage()
	{
		final SearchVO searchVO = new SearchVO();
		Integer currentPage = 2; 
		Integer pageSize = 5;
		searchVO.setPageNo(currentPage);
		searchVO.setPageSize(pageSize);
		
		final Page page = new Page();
		// expectations
		context.checking(new Expectations() {{
			oneOf(returnVisitRuleDao).queryByPage(searchVO); will(returnValue(page));
	    }});
		Page returnValue = serviceImpl.queryReturnVisitRuleListByPage(searchVO);
		context.assertIsSatisfied();
		assertNotNull(returnValue);
	}

}
